package com.ar4j.test;

import java.io.IOException;

import javax.sql.DataSource;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;

/**
 * Resets the ar4j test database, should be the first test to run in a test suite.
 * 
 * Runs as a non tansactional test to be able to apply DDL in a global transaction
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/applicationContext-junit.xml" })
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = false)
public class DatabaseReset implements ApplicationContextAware {

  @Autowired
  private DataSource dataSource;
  
  private String resetDbScript;
  private String resetSecondDbScript;
  private String initDbScript;
  private String setSchemaScript;
  
  @Test
  public void resetDatabase() {
    JdbcTemplate template = new JdbcTemplate(dataSource);
    runScript(template, resetDbScript);
    runScript(template, initDbScript);
    runScript(template, resetSecondDbScript);
    runScript(template, initDbScript);
    runScript(template, setSchemaScript);
  }
  
  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    Resource resetScript = applicationContext.getResource("/sql/reset-db.sql");
    Resource resetSecondScript = applicationContext.getResource("/sql/reset-db2.sql");
    Resource initScript = applicationContext.getResource("/sql/init-db.sql");
    Resource setScript = applicationContext.getResource("/sql/set-test-schema.sql");
    try {
      resetDbScript = IOUtils.toString(resetScript.getInputStream());
      resetSecondDbScript = IOUtils.toString(resetSecondScript.getInputStream());
      initDbScript = IOUtils.toString(initScript.getInputStream());
      setSchemaScript = IOUtils.toString(setScript.getInputStream());
    } catch(IOException e) {
      throw new RuntimeException("Could not get DB reset script", e);
    }
  }
  
  private void runScript(JdbcTemplate template, String script) {
    for(String qry : script.split(";--")) {
      if(StringUtils.isBlank(qry)) {
        continue;
      }
        
      template.update(qry);
    }
  }
  
}
